package 中等.双指针;

/**
 * 有时候人们会用重复写一些字母来表示额外的感受，比如 "hello" -> "heeellooo",
 * "hi" -> "hiii"。我们将相邻字母都相同的一串字符定义为相同字母组，例如：
 * "h", "eee", "ll", "ooo"。
 * 对于一个给定的字符串 S ，如果另一个单词能够通过将一些字母组扩张从而使其
 * 和 S 相同，我们将这个单词定义为可扩张的（stretchy）。扩张操作定义如下
 * ：选择一个字母组（包含字母 c ），然后往其中添加相同的字母 c 使其长度达
 * 到 3 或以上。
 * 例如，以 "hello" 为例，我们可以对字母组 "o" 扩张得到 "hellooo"，但是无
 * 法以同样的方法得到 "helloo" 因为字母组 "oo" 长度小于 3。此外，我们可
 * 以进行另一种扩张 "ll" -> "lllll" 以获得 "helllllooo"。如果 s = "helllllooo"
 * ，那么查询词 "hello" 是可扩张的，因为可以对它执行这两种扩张操作使
 * 得 query = "hello" -> "hellooo" -> "helllllooo" = s。
 * 输入一组查询单词，输出其中可扩张的单词数量。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/expressive-words
 */
public class 情感丰富的文字_809 {

    public static void main(String[] args) {

        System.out.println(expressiveWords("aaa", new String[]{"aaaaa"}));

    }

    /**
     * 双指针模拟
     * 当 word 中相对的连续相同字符为 2 个，且 s中对应字符不为 2 个时不满足条件
     * 当 word 中对应字符的数量超过 s 中的数量时不满足条件
     * 当 word 和 s 的字母组，字符相同，组数一致时，满足条件
     */
    public static int expressiveWords(String s, String[] words) {
        int count = 0;
        char[] sArr = s.toCharArray();
        for (String word : words) {
            char[] wArr = word.toCharArray();
            int sIdx = 0, wIdx = 0;
            while (sIdx < sArr.length && wIdx < wArr.length) {
                int curSIdx = sIdx, curWIdx = wIdx;
                while (curSIdx + 1 < sArr.length && sArr[curSIdx] == sArr[curSIdx + 1]) {
                    curSIdx++;
                }
                while (curWIdx + 1 < wArr.length && wArr[curWIdx] == wArr[curWIdx + 1]) {
                    curWIdx++;
                }

                if (sArr[curSIdx] != wArr[curWIdx] ||
                        curSIdx - sIdx + 1 == 2 && curWIdx - wIdx + 1 != 2 ||
                        curWIdx - wIdx > curSIdx - sIdx) {
                    break;
                }
                sIdx = curSIdx + 1;
                wIdx = curWIdx + 1;
            }
            if (sIdx == sArr.length && wIdx == wArr.length) {
                count++;
            }
        }
        return count;
    }

}
